package org.aspire.util;

import org.aspire.data.Data;

/******************************************************************************
 * Utility class for the implementation of different sorting algorithms.
 * 
 * @author JPACarabuena
 *****************************************************************************/
public final class Sort {

	// ========================================================================
	// Constants
	// ========================================================================

	/**************************************************************************
	 * Flag for sorting data in ascending order.
	 *************************************************************************/
	public static final int ASCENDING 	= 1;
	
	/**************************************************************************
	 * Flag for sorting data in descending order.
	 *************************************************************************/
	public static final int DESCENDING 	= -1;
	
	// ========================================================================
	// Static Methods
	// ========================================================================

	/**************************************************************************
	 * Swap the values of two object in the specified array.
	 * 
	 * @param data	the array containing the data to be swapped.
	 * @param i1	the index of the first data.
	 * @param i2	the index of the second data.
	 *************************************************************************/
	public static void swap(Object[] data, int i1, int i2) {
		Object temp = data[i1];
		data[i1] = data[i2];
		data[i2]= temp;
	}
	
	/**************************************************************************
	 * Implementation of the shell sort algorithm.
	 * 
	 * @param data	the enumeration of data to be sorted.
	 * @param datatype the type of the data to be sorted.
	 * @param order whether to sort data in descending or ascending order.
	 * @return	the sorted data.
	 *************************************************************************/
	public static Object[] shellSort(Object[] data, int datatype, int order) {
		int n = data.length;
		
		for(int k = n/2; k >= 1; k /= 2) {
			for(int i = k; i < n; i++) {
				for(int j = i; j > k-1; j-=k) {
					if(order == Sort.ASCENDING) {
						if(Data.compare(data[j], data[j-k], datatype) == -1) {
							Sort.swap(data, j, j-k);
						} else {
							break;
						}
					} else {
						if(Data.compare(data[j], data[j-k], datatype) == 1) {
							Sort.swap(data, j, j-k);
						} else {
							break;
						}
					}
				}
			}
		}
		
		return data;
	}
	
	// ========================================================================
	// Fields
	// ========================================================================

	// ========================================================================
	// Constructors
	// ========================================================================

	// ========================================================================
	// Getters & Setters
	// ========================================================================

	// ========================================================================
	// Override Methods
	// ========================================================================

	// ========================================================================
	// Methods
	// ========================================================================

	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}